package org.xx.armory.swing.builders;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.function.Consumer;

import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.xx.armory.commons.Validators.notBlank;

public final class SimpleAction
        extends AbstractAction {
    public static final String CAUSE_VERIFICATION_KEY = "_CauseVerificationKey_";
    private final Logger logger = LoggerFactory.getLogger(SimpleAction.class);
    private Consumer<ActionEvent> handler;

    /**
     * 构造一个SimpleAction对象。
     *
     * @param title
     *         标题，自动去掉首尾空格。
     * @param mnemonic
     *         快捷字符，{@literal '\0'}表示没有快捷字符。
     * @param accelerator
     *         快捷键，{@code null}表示没有分配快捷键。
     * @param smallIcon
     *         图标，{@code null}表示没有图标。
     * @param description
     *         描述，自动去掉首尾空格。
     * @param command
     *         附加的命令，自动去掉首尾空格。
     * @param causeVerification
     *         是否需要对所有输入域进行校验。
     * @throws IllegalArgumentException
     *         如果参数{@code getTitle}是{@code null}或者只包含空白字符。
     */
    public SimpleAction(
            String title,
            char mnemonic,
            KeyStroke accelerator,
            Icon smallIcon,
            String description,
            String command,
            boolean causeVerification
    ) {
        title = notBlank(title, "title").trim();
        super.putValue(Action.NAME, title);
        super.setEnabled(true);
        if (mnemonic != '\0') {
            super.putValue(Action.MNEMONIC_KEY, (int) mnemonic);
        }
        if (accelerator != null) {
            super.putValue(Action.ACCELERATOR_KEY, accelerator);
        }
        if (smallIcon != null) {
            super.putValue(Action.SMALL_ICON, smallIcon);
        }
        description = trimToEmpty(description);
        if (!description.isEmpty()) {
            super.putValue(Action.SHORT_DESCRIPTION, trimToEmpty(description));
        }
        command = trimToEmpty(command);
        if (!command.isEmpty()) {
            super.putValue(Action.ACTION_COMMAND_KEY, command);
        }
        super.putValue(CAUSE_VERIFICATION_KEY, causeVerification);
        this.handler = null;
    }

    /**
     * 克隆一个新的SimpleAction实例。
     *
     * @param src
     *         原Action实例。
     * @throws IllegalArgumentException
     *         如果参数{@code src}是{@code null}。
     */
    public SimpleAction(
            Action src
    ) {
        super.putValue(Action.NAME, src.getValue(Action.NAME));
        super.putValue(Action.MNEMONIC_KEY, src.getValue(Action.MNEMONIC_KEY));
        super.putValue(Action.ACCELERATOR_KEY, src.getValue(Action.ACCELERATOR_KEY));
        super.putValue(Action.SMALL_ICON, src.getValue(Action.SMALL_ICON));
        super.putValue(Action.SHORT_DESCRIPTION, src.getValue(Action.SHORT_DESCRIPTION));
        super.putValue(Action.ACTION_COMMAND_KEY, src.getValue(Action.ACTION_COMMAND_KEY));
        super.putValue(CAUSE_VERIFICATION_KEY, src.getValue(CAUSE_VERIFICATION_KEY));
        this.handler = null;
    }

    public boolean isCauseVerification() {
        final Object obj = super.getValue(CAUSE_VERIFICATION_KEY);
        if (obj == null) {
            return false;
        } else if (obj instanceof Boolean) {
            return (Boolean) obj;
        } else {
            return false;
        }
    }

    /**
     * 设置响应方法。
     *
     * @param handler
     *         响应方法。
     */
    public void setHandler(
            Consumer<ActionEvent> handler
    ) {
        this.handler = handler;
    }

    /**
     * {@inheritDoc}
     *
     * @param event
     *         触发Action的事件参数。
     */
    @Override
    public void actionPerformed(
            ActionEvent event
    ) {
        if (this.handler != null) {
            this.handler.accept(event);
        } else {
            logger.warn("null handler of {}[command={}]", getValue(Action.NAME), getValue(Action.ACTION_COMMAND_KEY));
        }
    }
}
